💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    1. 배포 설정 | ✅ 저자: 이유정(박사)

    settings.py

    import os
    ALLOWED_HOSTS = ["*"]
    
    INSTALLED_APPS = [
        "rest_framework",
        "restaurant",
    ]
    
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": os.environ.get("DB_NAME", "restaurant_db"),
            "USER": os.environ.get("DB_USER", "restaurant_user"),
            "PASSWORD": os.environ.get("DB_PASSWORD", "db_password"),
            "HOST": os.environ.get("DB_HOST", "localhost"),
            "PORT": os.environ.get("DB_PORT", "3306"),
            "OPTIONS": {"charset": "utf8mb4"},
        }
    }
    
    if os.environ.get("TEST"):
        DATABASES = {
            "default": {
                "ENGINE": "django.db.backends.sqlite3",
                "NAME": BASE_DIR / "db.sqlite3",
            }
        }
        
    LANGUAGE_CODE = "ko-kr"
    
    MEDIA_URL = "media/"
    MEDIA_ROOT = BASE_DIR / "media"
    
    # Use Amazon S3 for storage for uploaded media files if not debugging
    if os.environ.get("S3_BUCKET"):
        STORAGES = {
            "default": {
                "BACKEND": "storages.backends.s3.S3Storage",
                "OPTIONS": {
                    "bucket_name": os.environ.get("S3_BUCKET"),
                    "region_name": os.environ.get("S3_REGION", "ap-northeast-2"),
                    "custom_domain": os.environ.get("S3_CUSTOM_DOMAIN"),
                    "location": "media",
                    "default_acl": "public-read",
                    "querystring_auth": False,
                },
            },
            "staticfiles": {
                "BACKEND": "storages.backends.s3.S3Storage",
                "OPTIONS": {
                    "bucket_name": os.environ.get("S3_BUCKET"),
                    "region_name": os.environ.get("S3_REGION", "ap-northeast-2"),
                    "custom_domain": os.environ.get("S3_CUSTOM_DOMAIN"),
                    "location": "static",
                    "default_acl": "public-read",
                    "querystring_auth": False,
                },
            },
        }
    

    MySQL 서버 설치 확인

    sudo apt update # 시스템 패키지 업데이트
    sudo apt install mysql-server # MySQL 서버 설치
    
    # MySQL 서버 실행 및 자동 시작 설정
    sudo systemctl start mysql # MySQL 서버 실행
    sudo systemctl enable mysql # 시스템 부팅 시 MySQL 자동 시작 설정
    

    MySQL 사용자 및 데이터베이스 생성 MySQL 루트(root) 계정으로 접속

    sudo mysql -u root -p
    

    MySQL에서 Django용 데이터베이스 및 사용자 생성

    CREATE DATABASE restaurant_db DEFAULT CHARACTER SET utf8mb4;
    CREATE USER 'restaurant_user'@'localhost' IDENTIFIED BY 'db_password';
    GRANT ALL PRIVILEGES ON restaurant_db.* TO 'restaurant_user'@'localhost';
    FLUSH PRIVILEGES;
    
    • restaurant_db: Django가 사용할 MySQL 데이터베이스
    • restaurant_user: 접속할 MySQL 사용자
    • 'db_password': 사용자의 비밀번호 (이 값을 기억하고 settings.py와 일치시켜야 함)
    • FLUSH PRIVILEGES: 변경 사항 즉시 적용

    MySQL Python 드라이버 설치 (mysqlclient)

    sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
    pip install mysqlclient
    
    • 설명: Django에서 MySQL과 통신할 수 있도록 도와주는 파이썬 패키지 설치

    Django 설정 파일 settings.py에서 DB 연결 변경

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": "restaurant_db",
            "USER": "restaurant_user",
            "PASSWORD": "db_password",
            "HOST": "localhost",
            "PORT": "3306",
            "OPTIONS": {"charset": "utf8mb4"},
        }
    }
    
    • Django가 사용할 DB 엔진을 MySQL로 설정
    • 위에서 만든 DB, 유저, 비밀번호를 일치시킴

    비밀번호 오류 해결을 위한 비밀번호 재설정

    ALTER USER 'restaurant_user'@'localhost' IDENTIFIED BY 'db_password';
    FLUSH PRIVILEGES;
    

    마이그레이션 실행

    python manage.py migrate
    

    Django가 필요한 테이블들을 restaurant_db MySQL DB에 생성

    requirements.txt 파일 추가

    mysqlclient>=2.2.0
    

    .github/workflows/django-test.yml 수정

    name: Django CI
    
    on:
      push:
        branches: [ "main", "dev" ]
      pull_request:
        branches: [ "main", "dev" ]
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        services:
          mysql:
            image: mysql:8.0
            env:
              MYSQL_ROOT_PASSWORD: root
              MYSQL_DATABASE: restaurant_db
              MYSQL_USER: restaurant_user
              MYSQL_PASSWORD: db_password
            ports:
              - 3306:3306
            options: >-
              --health-cmd="mysqladmin ping --silent"
              --health-interval=10s
              --health-timeout=5s
              --health-retries=5
    
        strategy:
          matrix:
            python-version: [3.12.3]
    
        steps:
        - uses: actions/checkout@v4
    
        - name: Set up Python ${{ matrix.python-version }}
          uses: actions/setup-python@v5
          with:
            python-version: ${{ matrix.python-version }}
    
        - name: Install system dependencies for mysqlclient
          run: sudo apt-get install -y default-libmysqlclient-dev
    
        - name: Install Python dependencies
          run: |
            python -m pip install --upgrade pip
            pip install -r requirements.txt
    
        - name: Grant DB permissions to test user
          run: |
            sudo apt-get install -y default-mysql-client
            mysql -h 127.0.0.1 -u root -proot -e "
              CREATE USER IF NOT EXISTS 'restaurant_user'@'%' IDENTIFIED BY 'db_password';
              GRANT ALL PRIVILEGES ON *.* TO 'restaurant_user'@'%';
              FLUSH PRIVILEGES;
            "
    
        - name: Wait for MySQL to be ready
          run: |
            for i in {1..10}; do
              nc -z 127.0.0.1 3306 && echo "MySQL is up" && break
              echo "Waiting for MySQL..."
              sleep 5
            done
    
        - name: Run Tests
          env:
            DB_NAME: restaurant_db
            DB_USER: root
            DB_PASSWORD: root
            DB_HOST: 127.0.0.1
          run: |
            python manage.py test
    

    액션에서 CI통과가 되도록 yml파일을 설정한다.

    TOP
    preload preload